<script setup lang="tsx">
import { computed, ref } from 'vue';
import { Tag } from 'ant-design-vue';
import { $t } from '@/locales';
import {
  deleteScheduleTask,
  executeScheduleTask,
  fetchScheduleTask,
  startScheduleTask,
  stopScheduleTask
} from '@/service/api/schedule-task';
import ScheduleTaskOperateDrawer from './modules/schedule-task-operate-drawer.vue';
import ScheduleTaskSearch from './modules/schedule-task-search.vue';
import ScheduleTaskExecutionRecords from './modules/schedule-task-execution-records.vue';

defineOptions({
  name: 'ScheduleTaskManage'
});

// 表格数据
const loading = ref(false);
const taskList = ref<any[]>([]);
const searchParams = ref({
  keyword: '',
  status: undefined,
  nodeId: undefined
});

// 操作相关
const drawerVisible = ref(false);
const operateType = ref<'add' | 'edit'>('add');
const editingData = ref<any>(null);
const checkedRowKeys = ref<string[]>([]);

// 执行记录相关
const executionRecordsVisible = ref(false);
const selectedTask = ref<any>(null);

// 表格列定义
const columns = [
  {
    key: 'taskName',
    title: '任务名称',
    dataIndex: 'taskName',
    align: 'center' as const,
    width: 150,
    ellipsis: true
  },
  {
    key: 'description',
    title: '任务描述',
    dataIndex: 'description',
    align: 'center' as const,
    width: 200,
    ellipsis: true
  },
  {
    key: 'creator',
    title: '创建人',
    dataIndex: 'creator',
    align: 'center' as const,
    width: 100
  },
  {
    key: 'createTime',
    title: '创建时间',
    dataIndex: 'createTime',
    align: 'center' as const,
    width: 160
  },
  {
    key: 'status',
    title: '状态',
    dataIndex: 'running',
    align: 'center' as const,
    width: 100,
    customRender: ({ record }: any) => {
      const tagColor = record.running ? 'success' : 'default';
      const label = record.running ? '运行中' : '已停止';
      return <Tag color={tagColor}>{label}</Tag>;
    }
  },
  {
    key: 'cron',
    title: 'Cron表达式',
    dataIndex: 'cron',
    align: 'center' as const,
    width: 120,
    ellipsis: true
  },
  {
    key: 'beanName',
    title: '执行类名',
    dataIndex: 'beanName',
    align: 'center' as const,
    width: 150,
    ellipsis: true
  },
  {
    key: 'methodName',
    title: '方法名',
    dataIndex: 'methodName',
    align: 'center' as const,
    width: 120
  },
  {
    key: 'node',
    title: '节点',
    align: 'center' as const,
    width: 140,
    customRender: ({ record }: any) => {
      if (record.nodeIp && record.nodePort) {
        return `${record.nodeIp}:${record.nodePort}`;
      }
      return '-';
    }
  },
  {
    key: 'operate',
    title: $t('common.operate'),
    align: 'center' as const,
    width: 280
  }
];

// 行选择配置
const rowSelection = computed(() => ({
  selectedRowKeys: checkedRowKeys.value,
  onChange: (selectedRowKeys: any[], _selectedRows: any[]) => {
    checkedRowKeys.value = selectedRowKeys.map(key => String(key));
  }
}));

// 分页配置
const pagination = {
  showSizeChanger: true,
  showQuickJumper: true,
  showTotal: (total: number) => `共 ${total} 条记录`,
  pageSizeOptions: ['10', '20', '50', '100'],
  defaultPageSize: 20
};

// 获取数据
async function getData() {
  loading.value = true;
  const { data, error: err } = await fetchScheduleTask();
  if (err) {
    loading.value = false;
    return;
  }
  // 明确指定taskData为数组类型
  let taskData = (data as any) || [];

  // 前端筛选逻辑
  const { keyword, status, nodeId } = searchParams.value;
  if (keyword || status !== undefined || nodeId) {
    taskData = taskData?.filter((task: any) => {
      // 关键词筛选
      const keywordMatch =
        !keyword ||
        (task.taskName && task.taskName.includes(keyword)) ||
        (task.description && task.description.includes(keyword)) ||
        (task.beanName && task.beanName.includes(keyword)) ||
        (task.methodName && task.methodName.includes(keyword));

      // 状态筛选
      const statusMatch = status === undefined || task.running === (status === '1');

      // 节点筛选 - 确保task.node存在且是字符串类型再调用includes
      const nodeMatch = !nodeId || (typeof task.node === 'string' && task.node.includes(nodeId));

      return keywordMatch && statusMatch && nodeMatch;
    });
  }

  // 后端返回的是数组格式，直接处理数组
  if (Array.isArray(taskData)) {
    taskList.value = taskData.map((task: any) => {
      // 解析节点信息
      let nodeIp = '';
      let nodePort = '';
      if (task.node) {
        const [ip, port] = task.node.split(':');
        nodeIp = ip || '';
        nodePort = port || '';
      }

      return {
        taskId: task.id?.toString() || '',
        taskName: task.taskName || '',
        description: task.description || '',
        creator: task.creator || '',
        createTime: task.createTime || '',
        running: task.enabled || false, // 使用enabled字段作为运行状态
        runnable: task.enabled || false,
        cron: task.cron || '',
        beanName: task.beanName || '',
        methodName: task.methodName || '',
        nodeIp,
        nodePort,
        enabled: task.enabled || false // 添加enabled字段
      };
    });
  } else {
    // 如果返回的是对象格式（兼容旧格式）
    taskList.value = Object.entries(taskData)
      .filter(([taskId]) => !['data', 'error', 'response'].includes(taskId))
      .map(([taskId, info]: [string, any]) => {
        if (!info || typeof info !== 'object') return { taskId };
        const config = info.config || {};
        return {
          taskId,
          taskName: config.taskName || '',
          description: config.description || '',
          creator: config.creator || '',
          createTime: config.createTime || '',
          running: info.running || false,
          runnable: info.runnable || false,
          cron: config.cron || '',
          beanName: config.beanName || '',
          methodName: config.methodName || '',
          nodeIp: config.nodeIp || '',
          nodePort: config.nodePort || ''
        };
      });
  }
  loading.value = false;
}

// 操作函数
function handleAdd() {
  operateType.value = 'add';
  editingData.value = null;
  drawerVisible.value = true;
}

function handleEdit(record: any) {
  operateType.value = 'edit';
  editingData.value = record;
  drawerVisible.value = true;
}

async function toggleTaskStatus(record: any) {
  if (record.running) {
    const { error: err } = await stopScheduleTask(record.taskId);
    if (!err) {
      window.$message?.success('任务已停止');
      await getData();
    }
  } else {
    const { error: err } = await startScheduleTask(record.taskId);
    if (!err) {
      window.$message?.success('任务已启动');
      await getData();
    }
  }
}

async function handleExecute(record: any) {
  const { error: err } = await executeScheduleTask(record.taskId);
  if (!err) {
    window.$message?.success('任务执行成功');
  }
}

async function handleBatchDelete() {
  const deleteResults = await Promise.all(checkedRowKeys.value.map(id => deleteScheduleTask(id)));
  // 检查是否有删除失败的任务
  const hasError = deleteResults.some(result => result.error);
  if (!hasError) {
    window.$message?.success('批量删除成功');
    checkedRowKeys.value = [];
    await getData();
  } else {
    window.$message?.error('部分任务删除失败');
  }
}

async function handleDelete(taskId: string) {
  const { error: err } = await deleteScheduleTask(taskId);
  if (!err) {
    window.$message?.success('删除成功');
    await getData();
  }
}

function resetSearchParams() {
  searchParams.value = {
    keyword: '',
    status: undefined,
    nodeId: undefined
  };
  getData();
}

function onSearch() {
  getData();
}

// 显示执行记录
function handleShowExecutionRecords(record: any) {
  selectedTask.value = record;
  executionRecordsVisible.value = true;
}

// 初始化
getData();
</script>

<template>
  <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
    <ScheduleTaskSearch v-model:model="searchParams" @reset="resetSearchParams" @search="onSearch" />
    <ACard
      title="定时任务管理"
      :bordered="false"
      :body-style="{ flex: 1, overflow: 'hidden' }"
      class="flex-col-stretch sm:flex-1-hidden card-wrapper"
    >
      <template #extra>
        <div class="flex flex-wrap justify-end gap-x-12px gap-y-8px">
          <AButton size="small" ghost type="primary" @click="handleAdd">
            <template #icon>
              <icon-ic:round-plus class="align-sub text-icon" />
            </template>
            <span class="ml-8px">{{ $t('common.add') }}</span>
          </AButton>
          <APopconfirm
            title="确认批量删除选中的任务吗？"
            :disabled="checkedRowKeys.length === 0"
            @confirm="handleBatchDelete"
          >
            <AButton size="small" danger :disabled="checkedRowKeys.length === 0">
              <template #icon>
                <icon-ic-round-delete class="align-sub text-icon" />
              </template>
              <span class="ml-8px">批量删除</span>
            </AButton>
          </APopconfirm>
          <AButton size="small" @click="getData">
            <template #icon>
              <icon-mdi-refresh class="align-sub text-icon" :class="{ 'animate-spin': loading }" />
            </template>
            <span class="ml-8px">{{ $t('common.refresh') }}</span>
          </AButton>
        </div>
      </template>
      <ATable
        :columns="columns"
        :data-source="taskList"
        size="small"
        :row-selection="rowSelection"
        :loading="loading"
        row-key="taskId"
        :pagination="pagination"
        :scroll="{ x: 1200 }"
        class="h-full"
        :custom-row="(record: any) => ({
          onDblclick: () => handleShowExecutionRecords(record)
        })"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'operate'">
            <div class="flex-center gap-8px">
              <APopconfirm
                :title="record.running ? '确认停止此任务吗？' : '确认启动此任务吗？'"
                @confirm="toggleTaskStatus(record)"
              >
                <AButton
                  :type="record.running ? 'primary' : 'primary'"
                  :danger="record.running"
                  size="small"
                  class="btn-with-icon"
                >
                  <template #icon>
                    <icon-mdi-stop v-if="record.running" class="text-icon" />
                    <icon-mdi-play v-else class="text-icon" />
                  </template>
                </AButton>
              </APopconfirm>
              <APopconfirm title="确认立即运行此任务吗？" @confirm="handleExecute(record)">
                <AButton type="primary" size="small" class="btn-with-icon">
                  <template #icon>
                    <icon-mdi-play-circle class="text-icon" />
                  </template>
                </AButton>
              </APopconfirm>
              <AButton type="default" size="small" class="btn-with-icon" @click="handleShowExecutionRecords(record)">
                <template #icon>
                  <icon-mdi-history class="text-icon" />
                </template>
              </AButton>
              <AButton type="primary" ghost size="small" class="btn-with-icon" @click="handleEdit(record)">
                <template #icon>
                  <icon-mdi-pencil class="text-icon" />
                </template>
              </AButton>
              <APopconfirm :title="$t('common.confirmDelete')" @confirm="handleDelete(record.taskId)">
                <AButton danger size="small" class="btn-with-icon">
                  <template #icon>
                    <icon-mdi-delete class="text-icon" />
                  </template>
                </AButton>
              </APopconfirm>
            </div>
          </template>
        </template>
      </ATable>
    </ACard>
    <ScheduleTaskOperateDrawer
      v-model:open="drawerVisible"
      :operate-type="operateType"
      :row-data="editingData"
      @submitted="getData"
    />
    <ScheduleTaskExecutionRecords
      v-model:open="executionRecordsVisible"
      :task-id="selectedTask?.taskId"
      :task-name="selectedTask?.taskName"
    />
  </div>
</template>

<style scoped>
/* 按钮图标和文字对齐 */
.btn-with-icon {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 4px !important;
  line-height: 1 !important;
}

.btn-with-icon .anticon {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}

/* 确保 SVG 图标与文字垂直居中对齐 */
.btn-with-icon svg {
  width: 1em !important;
  height: 1em !important;
  vertical-align: middle !important;
  display: inline-block !important;
}
</style>
